home *** CD-ROM | disk | FTP | other *** search
- Path: jabba.ess.harris.com!usenet
- From: "Timothy R. Culp" <tculp@harris.com>
- Newsgroups: comp.lang.c++
- Subject: Re: Reading derived-class objects in from a file -- possible?
- Date: 4 Jan 1996 02:25:36 GMT
- Organization: Harris ISD
- Message-ID: <4cfdr0$ocv@jabba.ess.harris.com>
- References: <4ceho4$re6@lace.colorado.edu>
- NNTP-Posting-Host: xtwa3.ess.harris.com
-
- Robert Dodier <dodier@colorado.edu> wrote:
- >
- > Hello,
- >
- > I have a simple question but I can't seem to find a simple answer. :)
- >
- > I have an abstract class, let's call it class A, and two derived classes
- > B and C. I would *like* to do something like this (never mind that, as
- > stated below, it can't work).
- >
- > A* p_something = new A;
- > cin >> *p_something;
- > p_something->do_whatever();
- >
- > Within the program, I don't really care if someone gives a B or a C as
- > input -- I'll use the virtual functions of A for access anyway.
- >
- > I don't want to have to write:
- >
- > cin >> ident;
- > switch ( ident ) {
- > case 'B': p_something = new B; break;
- > case 'C': p_something = new C; break;
- > }
-
- You've touched on a classic problem that plagues everyone and
- unfortunately the elegant answer isn't simple.
-
- The simplest way to approach the problem is to bury the details
- of how your abstract class gets created into another class. There
- is a book on the market now called "Design Patterns" that shows
- an implementation of an "abstract factory" or an "object factory"
- that deals with the problem. Just create another class called an
- A_Maker that polymorphically constructs an A from some input:
-
- A* p_something = A_Maker::newA(some identifier);
-
- Your A_Maker::newA() method can be as simple as your switch
- statement up above. The only problem with that is every time
- a new derived class is created from A, you have to remember to
- modify your A_Maker::newA() method.
-
- A more elegant approach involves having your A_Maker class contain
- a linked list of A pointers. Each derived class automatically
- links themselves into the A_Maker list. Each derived class is
- also responsible for providing a method that returns true when
- passed an identifier. Your A_Maker::newA() method will then loop
- through the list, asking each pointer if it matches the identifier
- passed in. If so, it returns an instance of that pointer.
-
- A_Maker::newCell(const string& ident)
- {
- A* a = list->head(); // linked list of A ptrs;
- A* found = 0;
-
- while (a && !found)
- {
- if (a->isMyIdent(ident))
- {
- found = a->instanceOfMe();
- }
- else a = list->next();
- }
-
- return found;
- }
-
- Timothy Culp
- Lead Software Engineer
- Harris Information Systems
- tculp@harris.com
-